<template>
  <div class="table-qvil-wrapper">
    <div class="table-qvil-container">
      <div class="table-qvil">
        <el-table
          ref="tableRef"
          v-loading="state.loading"
          :border="border"
          v-bind="$attrs"
          class="table-main"
          :data="state.data"
          :height="height ? height : '100%'"
          :stripe="stripe"
          @row-click="handleRowClick"
          @selection-change="handleSelectionChange"
        >
          <!-- 序号列 -->
          <el-table-column v-if="showIndex" fixed="left" label="序号" type="index" width="60" />

          <!-- 选择列 -->
          <el-table-column v-if="$attrs['row-key']" fixed="left" type="selection" width="55" />

          <!-- 数据列 -->
          <template v-for="col in columns" :key="col.prop">
            <el-table-column
              :align="col.align || 'left'"
              :fixed="col.fixed"
              :label="col.label"
              :min-width="col.minWidth"
              :prop="col.prop"
              :show-overflow-tooltip="col.showOverflowTooltip"
              :sortable="col.sortable"
              :width="col.width"
            >
              <template #default="scope">
                <!-- 渲染优先级：
                  1. 命名插槽
                  2. 自定义组件
                  3. formatter函数
                  4. 默认显示
                -->
                <!-- 1. 使用命名插槽 -->
                <slot
                  v-if="$slots[`column-${col.prop}`]"
                  :column="col"
                  :index="scope.$index"
                  :name="`column-${col.prop}`"
                  :row="scope.row"
                />
                <!-- 2. 使用自定义组件 -->
                <component
                  :is="col.component"
                  v-else-if="col.component"
                  v-bind="col.componentProps || {}"
                  :row="scope.row"
                  :value="scope.row[col.prop]"
                  @update:value="(val) => updateColumnValue(scope.row, col.prop, val)"
                />
                <!-- 3. 使用formatter函数 -->
                <template v-else-if="col.formatter">
                  {{ col.formatter(scope.row, col.prop, scope.row[col.prop], scope.$index) }}
                </template>
                <!-- 4. 默认渲染 -->
                <template v-else>
                  {{ scope.row[col.prop] }}
                </template>
              </template>
            </el-table-column>
          </template>
        </el-table>

        <!-- 分页 -->
        <div class="pagination-container">
          <el-pagination
            v-model:current-page="state.pagination.currentPage"
            v-model:page-size="state.pagination.pageSize"
            :layout="state.pagination.layout"
            :page-sizes="state.pagination.pageSizes"
            :total="state.pagination.total"
            @current-change="handlePageChange"
            @size-change="handleSizeChange"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
// eslint-disable-next-line no-unused-vars
import { watch } from 'vue'
import { useTable } from './hooks/useTable'
import type { TableColumn } from './types'

const props = defineProps<{
  columns: TableColumn[]
  border?: boolean
  stripe?: boolean
  showIndex?: boolean
  data?: any[]
  loading?: boolean
  page?: number
  'page-size'?: number
  total?: number
  height?: string | number
}>()

const emit = defineEmits<{
  (e: 'page-change', page: number): void
  (e: 'size-change', size: number): void
  (e: 'row-click', row: any): void
  (e: 'selection-change', selection: any[]): void
  (e: 'update:page', page: number): void
  (e: 'update:page-size', size: number): void
}>()

const { state, tableRef, setData, setLoading, setPagination } = useTable({
  columns: props.columns,
  data: props.data,
  loading: props.loading,
  pagination: {
    currentPage: props.page || 1,
    pageSize: props['page-size'] || 10,
    total: props.total || 0,
  },
})

// 处理页码变化
const handlePageChange = (page: number) => {
  emit('page-change', page)
  emit('update:page', page)
}

// 处理每页条数变化
const handleSizeChange = (size: number) => {
  emit('size-change', size)
  emit('update:page-size', size)
}

// 处理行点击
const handleRowClick = (row: any) => {
  emit('row-click', row)
}

// 处理选择变化
const handleSelectionChange = (selection: any[]) => {
  emit('selection-change', selection)
}

// 添加更新列值的方法
const updateColumnValue = (row: any, prop: string, value: any) => {
  if (row && prop) {
    row[prop] = value
  }
}

// 监听属性变化
watch(
  () => props.data,
  (newVal) => {
    if (newVal && JSON.stringify(newVal) !== JSON.stringify(state.data)) {
      setData(newVal)
    }
  },
  { immediate: true }
)

watch(
  () => props.loading,
  (newVal) => {
    if (newVal !== undefined && newVal !== state.loading) {
      setLoading(newVal)
    }
  },
  { immediate: true }
)

watch(
  () => [props.page, props['page-size'], props.total],
  ([page, pageSize, total]) => {
    const pagination: Record<string, any> = {}
    let hasChanges = false

    if (page !== undefined && page !== state.pagination.currentPage) {
      pagination.currentPage = page
      hasChanges = true
    }
    if (pageSize !== undefined && pageSize !== state.pagination.pageSize) {
      pagination.pageSize = pageSize
      hasChanges = true
    }
    if (total !== undefined && total !== state.pagination.total) {
      pagination.total = total
      hasChanges = true
    }

    if (hasChanges) {
      setPagination(pagination)
    }
  },
  { immediate: true, deep: true }
)

// 暴露方法
defineExpose({
  setData,
  setLoading,
  setPagination,
  tableRef,
})
</script>

<style lang="scss" scoped>
.table-qvil-wrapper {
  margin: 0;
  display: flex;
  flex-direction: column;
  height: 100%;
  flex: 1;
}

.table-qvil-container {
  border-radius: 8px;
  border: 1px solid #ebeef5;
  background-color: #fff;
  overflow: hidden;
  flex: 1;
  display: flex;
  flex-direction: column;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.03);
  transition: all 0.3s;

  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
  }
}

.table-qvil {
  padding: 16px;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0; /* 确保flex子元素可以收缩 */

  .table-main {
    flex: 1;
    width: 100%;
    /* 确保表格可以在容器中正确展示 */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-height: calc(100vh - 300px);
    overflow-y: auto;
  }

  /* 表格行悬停效果优化 */
  :deep(.el-table__row) {
    transition: all 0.15s;
  }

  :deep(.el-table__row:hover) {
    background-color: var(--el-fill-color-lighter) !important;
  }

  /* 表格表头居中样式 */
  :deep(.el-table__header th) {
    text-align: center;
  }

  /* 表格空数据样式 */
  :deep(.el-table__empty-text) {
    padding: 40px 0;
    color: var(--el-text-color-secondary);
  }
}

.pagination-container {
  display: flex;
  justify-content: flex-end;
  padding: 8px 0;
  margin-top: 16px;
}
</style>
